package com.fh.shop.api.member.biz;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.fh.shop.api.common.Constant;
import com.fh.shop.api.common.ResponseEnum;
import com.fh.shop.api.common.ServerResponse;
import com.fh.shop.api.member.mapper.IMemberMapper;
import com.fh.shop.api.member.param.EditPwdParam;
import com.fh.shop.api.member.param.MemberLoginParam;
import com.fh.shop.api.member.param.MemberParam;
import com.fh.shop.api.member.po.Member;
import com.fh.shop.api.member.vo.MemberVo;
import com.fh.shop.api.util.*;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Base64;
import java.util.UUID;

@Service("memberService")
@Transactional(rollbackFor = Exception.class)
public class IMemberServiceImpl implements IMemberService {
    @Resource
    private IMemberMapper memberMapper;
    @Autowired
    private MailUtil mailUtil;
    @Value("${member.activa}")
    private String memberActiva;

    @Override
    public ServerResponse reg(MemberParam memberParam) {
        String memberName = memberParam.getMemberName();
        String mail = memberParam.getMail();
        String password = memberParam.getPassword();
        String nickName = memberParam.getNickName();
        String phone = memberParam.getPhone();
        String confirmPassword = memberParam.getConfirmPassword();
        String phoneCode = memberParam.getPhoneCode();

        //非空判断
        if (StringUtils.isEmpty(memberName)
                || StringUtils.isEmpty(mail)
                || StringUtils.isEmpty(password)
                || StringUtils.isEmpty(nickName)
                || StringUtils.isEmpty(phone)
                || StringUtils.isEmpty(confirmPassword)
                || StringUtils.isEmpty(phoneCode)){
            return ServerResponse.error(ResponseEnum.MEMBER_INFO_IS_NULL);
        }

        //判断密码是否一致
        if (!confirmPassword.equals(password)){
            return ServerResponse.error(ResponseEnum.MEMBER_PWD_MISMATCH);
        }

        //判断邮箱格式是否正确
        if (!RegUtil.isMail(mail)){
            return ServerResponse.error(ResponseEnum.MEMBER_MAIL_ERROR);
        }

        //判断手机号格式是否正确
        if (!RegUtil.isPhone(phone)){
            return ServerResponse.error(ResponseEnum.MEMBER_PHONE_ERROR);
        }

        //判断验证码是否正确
        String code = RedisUtil.get(KeyUtil.regCodeKey(phone));
        if (!phoneCode.equals(code)){
            return ServerResponse.error(ResponseEnum.MEMBER_CODE_MISMATCH);
        }

        //判断会员名唯一性
        QueryWrapper<Member> memberNameQueryWrapper = new QueryWrapper<>();
        memberNameQueryWrapper.eq("memberName",memberName);
        Member member = memberMapper.selectOne(memberNameQueryWrapper);
        if (member != null){
            return ServerResponse.error(ResponseEnum.MEMBER_NAME_EXIST);
        }

        //判断邮箱唯一性
        QueryWrapper<Member> memberMailQueryWrapper = new QueryWrapper<>();
        memberMailQueryWrapper.eq("mail",mail);
        Member member1 = memberMapper.selectOne(memberMailQueryWrapper);
        if (member1 != null){
            return ServerResponse.error(ResponseEnum.MEMBER_MAIL_EXIST);
        }

        //判断手机号唯一性
        QueryWrapper<Member> memberPhoneQueryWrapper = new QueryWrapper<>();
        memberPhoneQueryWrapper.eq("phone",phone);
        Member member2 = memberMapper.selectOne(memberPhoneQueryWrapper);
        if (member2 != null){
            return ServerResponse.error(ResponseEnum.MEMBER_PHONE_EXIST);
        }

        //插入数据库
        memberMapper.insert(memberParam);

        //发送邮件提示激活
        String uuid = UUID.randomUUID().toString();
        Long id = memberParam.getId();
        String key = KeyUtil.ActivaKey(uuid);
        mailUtil.sendMail(mail,memberActiva,"点击<a href='http://localhost:8085/api/member/activa/"+uuid+"'>激活</a>会员");

        //将id存入缓存中
        RedisUtil.setex(key,id.toString(),Constant.ACTIVA_TIME);

        //删除缓存中的验证码
        RedisUtil.del(KeyUtil.regCodeKey(phone));

        return ServerResponse.success();
    }

    @Override
    public ServerResponse login(MemberLoginParam memberLoginParam) {
        String memberName = memberLoginParam.getMemberName();
        String password = memberLoginParam.getPassword();
        //非空验证
        if (StringUtils.isEmpty(memberName) || StringUtils.isEmpty(password)){
            return ServerResponse.error(ResponseEnum.MEMBER_LOGIN_IS_NULL);
        }

        //验证账号
        QueryWrapper<Member> memberQueryWrapper = new QueryWrapper<>();
        memberQueryWrapper.eq("memberName",memberName);
        Member member = memberMapper.selectOne(memberQueryWrapper);
        if (member == null){
            return ServerResponse.error(ResponseEnum.MEMBER_LOGIN_MEMBERNAME_ERROR);
        }

        //验证密码
        String memberPassword = member.getPassword();
        if (!password.equals(memberPassword)){
            return ServerResponse.error(ResponseEnum.MEMBER_LOGIN_PWD_ERROR);
        }

        //验证状态
        Integer status = member.getStatus();
        if (status.intValue() == Constant.INACTIVA){
            return ServerResponse.error(ResponseEnum.MEMBER_INACTIVA);
        }

        //将用户信息放入到vo中
        MemberVo memberVo = new MemberVo();
        Long id = member.getId();
        memberVo.setId(id);
        memberVo.setNickName(member.getNickName());
        String uuid = UUID.randomUUID().toString();
        memberVo.setUuid(uuid);

        //将用户信息的对象转换为字符串
        String memberVoJson = JSON.toJSONString(memberVo);
        //将用户信息的字符串进行Base64编码
        String base64MemberVo = Base64.getEncoder().encodeToString(memberVoJson.getBytes());

        //将用户信息加密  签名+密钥
        String sign = Md5Util.sign(memberVoJson, Constant.SECRET);
        //将签名进行加密
        String base64Sign = Base64.getEncoder().encodeToString(sign.getBytes());

        //返回信息
        String result = base64MemberVo + "." + base64Sign;

        //存入缓存中,设置过期时间
        RedisUtil.setex(KeyUtil.memberKey(id),uuid,Constant.MEMBER_EXPIRATION);

        return ServerResponse.success(result);
    }

    @Override
    public ServerResponse editPwd(EditPwdParam editPwdParam) {
        Long id = editPwdParam.getId();
        String oldPwd = editPwdParam.getOldPwd();
        String newPwd = editPwdParam.getNewPwd();
        String confirmPwd = editPwdParam.getConfirmPwd();
        //非空验证
        if (StringUtils.isEmpty(oldPwd) || StringUtils.isEmpty(newPwd) || StringUtils.isEmpty(confirmPwd)){
            return ServerResponse.error(ResponseEnum.EDIT_PWD_IS_NULL);
        }
        //判断确认密码
        if (!newPwd.equals(confirmPwd)){
            return ServerResponse.error(ResponseEnum.EDIT_PWD_MISMATCH);
        }
        //判断原密码是否正确
        Member member = memberMapper.selectById(id);
        if (!member.getPassword().equals(oldPwd)){
            return ServerResponse.error(ResponseEnum.EDIT_PWD_OLDPWD_ERROR);
        }
        //修改数据
        Member memberEdit = new Member();
        memberEdit.setId(id);
        memberEdit.setPassword(newPwd);
        memberMapper.updateById(memberEdit);

        return ServerResponse.success();
    }

    //激活会员
    @Override
    public int updateStatus(String uuid) {

        //获取缓存中的id
        String key = KeyUtil.ActivaKey(uuid);
        String id = RedisUtil.get(key);

        //id非空验证
        if (StringUtils.isEmpty(id)){
            return Constant.ACTIVA_ERROR;
        }

        //修改会员状态
        Member member = new Member();
        member.setId(Long.parseLong(id));
        member.setStatus(Constant.ACTIVA_STATUS);
        memberMapper.updateById(member);

        //激活后清除redis
        RedisUtil.del(key);

        return Constant.ACTIVA_SUCCESS;
    }

    @Override
    public ServerResponse memberActiva(String mail) {
        //判断邮箱格式
        if (!RegUtil.isMail(mail)){
            return ServerResponse.error(ResponseEnum.MEMBER_MAIL_ERROR);
        }
        //验证邮箱
        QueryWrapper<Member> memberQueryWrapper = new QueryWrapper<>();
        memberQueryWrapper.eq("mail",mail);
        Member member = memberMapper.selectOne(memberQueryWrapper);
        if (member == null){
            return ServerResponse.error(ResponseEnum.MEMBER_MAIL_IS_ERROR);
        }

        //发送邮件提示激活
        String uuid = UUID.randomUUID().toString();
        String key = KeyUtil.ActivaKey(uuid);
        mailUtil.sendMail(mail,memberActiva,"点击<a href='http://localhost:8085/api/member/activaByMail/?uuid="+uuid+"'>激活</a>会员");

        //将id存入缓存中
        RedisUtil.setex(key,mail,Constant.ACTIVA_TIME);


        return ServerResponse.success();
    }

    @Override
    public boolean updateStatusByMail(String uuid) {
        //获取redis缓存中的mail
        String key = KeyUtil.ActivaKey(uuid);
        String mail = RedisUtil.get(key);

        //非空验证
        if (StringUtils.isEmpty(mail)){
            return false;
        }

        //修改会员状态
        Member member = new Member();
        member.setStatus(Constant.ACTIVA_STATUS);
        QueryWrapper<Member> updateWrapper = new QueryWrapper<>();
        updateWrapper.eq("mail",mail);
        memberMapper.update(member, updateWrapper);

        //清除redis
        RedisUtil.del(key);

        return true;
    }


}
